using System;
using System.IO;
using LaTrompa.Validation;

namespace CoverageRunner
{
    public class CodeCoverageParams
    {
        private void setAssembliesToInstrument(string[] assembliesToInstrument)
        {
            var validator = new Validator();
            validator.CheckThat(() => assembliesToInstrument).IsNotNull().CountIsMoreThan(0).ThrowFirst();
            foreach (var assembly in assembliesToInstrument)
            {
                if (!assembly.ToLower().EndsWith(".dll"))
                    throw new InvalidFormatException(string.Format("All the assembly names have to end on .dll. {0} doesn't.", assembly)); 
            }
            AssembliesToInstrument = assembliesToInstrument;
        }

        private void setInstrLocation()
        {
            var environmentVariable = Environment.GetEnvironmentVariables()["VS90COMNTOOLS"];
            if(environmentVariable == null) return;
            VsTsInstrLocation = Environment.GetEnvironmentVariables()["VS90COMNTOOLS"].ToString().Replace("Common7\\Tools\\","Team Tools\\Performance Tools\\");
        }
        
        private void setUnitTestExeAndArguments(string unitTestRunnerExecutable, string[] unitTestArguments)
        {
            var validator = new Validator();
            validator.CheckThat(() => unitTestRunnerExecutable)
                .IsNotNullOrEmpty<ArgumentException>(new[] { "You need to provide the location for the unit test executable." })
                .ThrowFirst();
            validator.CheckThat(() => unitTestArguments).IsNotNull<ArgumentException>(new[] { "You need to provide at least one argument for the unit test executable to indicate witch dll contains the test." })
                .CountIsMoreThan<ArgumentException>(0, new[] { "You need to provide at least one argument for the unit test executable to indicate witch dll contains the test." })
                .ThrowFirst();
            UnitTestRunnerExecutable = unitTestRunnerExecutable;
            UnitTestArguments = unitTestArguments;
        }

        public CodeCoverageParams(string[] assembliesToInstrument, string unitTestRunnerExecutable, string[] unitTestArguments)
        {
            setUnitTestExeAndArguments(unitTestRunnerExecutable, unitTestArguments);
            setInstrLocation();
            setAssembliesToInstrument(assembliesToInstrument);
        }

        public string[] AssembliesToInstrument { get; private set; }
        private string _pathToCodeToInstrument;
        public string PathToCodeToInstrument
        {
            get { return _pathToCodeToInstrument ?? Path.GetFullPath("."); }
            set { _pathToCodeToInstrument = value; }
        }

        public string VsTsInstrLocation { get; set; }
        public string UnitTestRunnerExecutable { get; private set; }
        public string[] UnitTestArguments { get; private set; }
        
        private string _vstsCoverageOutputFile;
        public string VstsCoverageOutputFile
        {
            get { return _vstsCoverageOutputFile ?? string.Format("{0}\\test.coverage", PathToCodeToInstrument); }
            set { _vstsCoverageOutputFile = value; }
        }

        private string _symbolsPath;
        public string SymbolsPath
        {
            get { return _symbolsPath ?? PathToCodeToInstrument; }
            set { _symbolsPath = value; }
        }

        private string _exePath;
        public string ExePath
        {
            get { return _exePath ?? PathToCodeToInstrument; }
            set { _exePath = value; }
        }

        private string _outputXml;
        public string OutputXml
        {
            get { return _outputXml ?? string.Format("{0}\\reports\\report.html", PathToCodeToInstrument); }
            set { _outputXml = value; }
        }

        public string CoverageXslt { get; set; }

        private string _outputHtml;
        public string OutputHtml
        {
            get { return _outputHtml ?? string.Format("{0}\\reports\\report.xml", PathToCodeToInstrument); }
            set { _outputHtml = value; }
        }
    }
}